﻿Imports System.ComponentModel
Imports System.ComponentModel.Composition
Imports System.ComponentModel.Composition.Hosting
Imports iConverter.Contracts
Imports System.Drawing
Imports System.Configuration

Namespace Extensions

    ''' <summary>
    ''' 扩展提供器
    ''' </summary>
    ''' <remarks></remarks>
    Public Class PluginProvider
        Implements IDisposable



        Dim _provider As Lazy(Of IPluginProvider, IPluginProviderMetadata)


        ''' <summary>
        ''' 创建新的实例
        ''' </summary>
        ''' <param name="provider">由MEF查找并填充的 扩展提供器对象</param>
        ''' <remarks></remarks>
        Friend Sub New(ByVal provider As Lazy(Of IPluginProvider, IPluginProviderMetadata))
            MyClass.New(provider, True)

        End Sub
        ''' <summary>
        ''' 创建新的实例
        ''' </summary>
        ''' <param name="provider">由MEF查找并填充的 扩展提供器对象</param>
        ''' <param name="isEnabled">指示插件否是启用</param>
        ''' <remarks></remarks>
        Friend Sub New(provider As Lazy(Of IPluginProvider, IPluginProviderMetadata), ByVal isEnabled As Boolean)
            Me.IsEnabled = isEnabled
            Me._provider = provider

            _id = New Guid(Me.Metadata.ID)

         
            If Not String.IsNullOrEmpty(Me.Metadata.Icon) Then

                '获取资源文件名
                Dim Resourcename =
                    Me.Metadata.Type.Assembly.GetManifestResourceNames.Where(Function(name) (
                                                                                 name.EndsWith(Me.Metadata.Icon, StringComparison.OrdinalIgnoreCase)
                                                                                 )
                                                                             ).FirstOrDefault


                If Not String.IsNullOrEmpty(Resourcename) Then
                    Dim resource = Me.Metadata.Type.Assembly.GetManifestResourceStream(Resourcename)
                    Me._icon = ExtensionsFactory.TryGetImageSource(resource)

                Else
                    'TODO: 增加 默认图标
                    Me._icon = Nothing
                End If

            End If


            'If _version Is Nothing Then
            _version = New Version(Me.Metadata.Version)
            'End If
        End Sub



#Region "元数据"
        ''' <summary>
        ''' 元数据
        ''' </summary>
        Private ReadOnly Property Metadata() As IPluginProviderMetadata
            Get
                Return Me._provider.Metadata
            End Get
        End Property

        ''' <summary>
        ''' 获取扩展提供器的描述
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Description As String
            Get
                Return Me.Metadata.Description
            End Get
        End Property

        ''' <summary>
        ''' 获取扩展提供器的名字
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Name As String
            Get
                Return Me.Metadata.Name
            End Get
        End Property

        ''' <summary>
        ''' 获取扩展提供器的作者
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Author As String
            Get
                Return Me.Metadata.Author
            End Get
        End Property


        Dim _icon As ImageSource

        ''' <summary>
        ''' 获取扩展提供器的图标
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Icon As ImageSource
            Get
                Return Me._icon
            End Get
        End Property

        Private _id As Guid

        ''' <summary>
        ''' 获取扩展提供器的GUID
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property ID As Guid
            Get
                Return _id
            End Get
        End Property


        Private _version As Version
        ''' <summary>
        ''' 获取扩展提供器的版本
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Version As Version
            Get
                Return _version
            End Get
        End Property

#End Region

#Region "IPluginProvider 方法"

        ''' <summary>
        ''' 插件提供器
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private ReadOnly Property Provider() As IPluginProvider
            Get
                Return Me._provider.Value
            End Get
        End Property

        ''' <summary>
        ''' 指示插件是否需要配置
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property CanConfigure As Boolean
            Get
                If Me.IsEnabled Then
                    Return Provider.CanConfigure
                End If
                Return False
            End Get
        End Property

        Dim _configurator As IPluginConfigurator

        ''' <summary>
        ''' 获取配置器
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks>用于修改扩展设置的自定义界面控件</remarks>
        Public ReadOnly Property Configurator As Contracts.IPluginConfigurator
            Get
                If Not Me.IsEnabled Then
                    Return Nothing
                End If
                If Me._configurator Is Nothing Then
                    Me._configurator = Me.Provider.GetConfigurator
                End If
                Return Me._configurator
            End Get
        End Property


        Dim _settings As ApplicationSettingsBase

        ''' <summary>
        ''' 获取扩展设置
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks>
        ''' 获取用于对扩展设置用于主程序管理
        ''' </remarks>
        Public ReadOnly Property Settings As ApplicationSettingsBase
            Get
                If Not Me.IsEnabled Then Return Nothing

                If Me._settings Is Nothing Then
                    Me._settings = Me.Provider.GetSettings
                End If
                Return Me._settings
            End Get
        End Property


        Dim _plugins As List(Of Plugin)

        ''' <summary>
        ''' 获取插件对象列表
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Plugins As List(Of Plugin)
            Get
                If Not Me.IsEnabled Then Return Nothing

                If Me._plugins Is Nothing Then
                    Me._plugins = ExtensionsFactory.CreatePlugins(Me, Me.Provider.GetPlugins)
                End If

                Return Me._plugins
            End Get
        End Property




#End Region


#Region "其他"

        ''' <summary>
        ''' 获取或设置一个值，指示 扩展提供器是否可用
        ''' </summary>
        ''' <value></value>
        ''' <returns>当扩展提供器可用时返回True，否则返回False</returns>
        ''' <remarks>
        ''' 当扩展提供器未被禁用时，返回 True ，否则返回false
        ''' </remarks>
        Friend Property IsEnabled As Boolean



#End Region


#Region "IDisposable Support"
        Private disposedValue As Boolean ' 检测冗余的调用

        ' IDisposable
        Protected Overridable Sub Dispose(disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    For Each p In Me._plugins
                        p.Dispose()
                    Next

                    Me._plugins.Clear()
                End If

                Me._configurator = Nothing
                Me._icon = Nothing
                Me._plugins = Nothing
                Me._settings = Nothing
                Me._version = Nothing
                Me._provider = Nothing
            End If
            Me.disposedValue = True
        End Sub


        'Protected Overrides Sub Finalize()
        '    ' 不要更改此代码。请将清理代码放入上面的 Dispose(ByVal disposing As Boolean)中。
        '    Dispose(False)
        '    MyBase.Finalize()
        'End Sub

        ' Visual Basic 添加此代码是为了正确实现可处置模式。
        Public Sub Dispose() Implements IDisposable.Dispose
            ' 不要更改此代码。请将清理代码放入上面的 Dispose(ByVal disposing As Boolean)中。
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
#End Region

    End Class

End Namespace